/*
只留一个北京消除的画面
给lijiqiao用
*/

#include <iostream>
#include "func.h"
const char* params
    = "{ help h         |           | Print usage }"
      "{ input          |           | Path to a video or a sequence of image }"
      "{ dirinput       |           | dir Path to a video or a sequence of image }"
      "{ show           |           | show or not  }"
      "{ output         |           | output path }"
      "{ lr             | -1        | learning rate of MOG2 }"
      "{ algo           | KNN       | Background subtraction method (KNN, MOG2) }";
int main(int argc, char* argv[])
{
    cv::CommandLineParser parser(argc, argv, params);
    parser.about( "This program shows how to use background subtraction methods provided by "
                  " OpenCV. You can process both videos and images.\n" );
    if (parser.has("help"))
    {
        //print help information
        parser.printMessage();
		return 0;    
	}
    //create Background Subtractor objects
	std::vector<std::string> files;
    if (parser.has("dirinput")){
		getFileNames( parser.get<cv::String>("dirinput")  , files);
		for(int i=0;i < files.size(); ++i){
			files[i] = parser.get<cv::String>("dirinput") +"/"+ files[i];
		}
	}
	if (parser.has("input")){
		files.push_back(parser.get<cv::String>("input") );
	}
    for (int i = 0; i < files.size(); ++i){
    	std::string filePath = files[i];
		std::cout<<"processing "<<files[i]<<std::endl;
	    cv::Ptr<cv::BackgroundSubtractor> pBackSub;
    	if (parser.get<cv::String>("algo") == "MOG2")
        	pBackSub = cv::createBackgroundSubtractorMOG2(500,16,true);
    	else
        	pBackSub = cv::createBackgroundSubtractorKNN(500,400,true);
	    cv::VideoCapture capture(filePath);
        if (!capture.isOpened()){
            //error in opening the video input
            std::cerr << "Unable to open: " << parser.get<cv::String>("input") << std::endl;
            return 0;
        }
		cv::Mat frame, fgMask;
		cv::VideoWriter videoWriter;
	    int width =(int)capture.get(cv::CAP_PROP_FRAME_WIDTH);
	    int height = (int)capture.get(cv::CAP_PROP_FRAME_HEIGHT);
        cv::Size S = cv::Size((int)capture.get(cv::CAP_PROP_FRAME_WIDTH),(int)capture.get(cv::CAP_PROP_FRAME_HEIGHT));
        int fps = capture.get(cv::CAP_PROP_FPS)/2;
		if (parser.has("output")){
			std::string::size_type iPos = filePath.find_last_of('/') + 1;
			std::string filename = files[i].substr(iPos, files[i].length() - iPos);
			filename = filename.substr(0, filename.rfind("."));
			videoWriter.open(parser.get<cv::String>("output")+"/OUT_"+filename+".avi", cv::VideoWriter::fourcc('M','J','P','G'),fps ,S);
		}        
		bool flag = 1;
        while (true) {
            capture >> frame;
            if (frame.empty())
                break;
			flag^=1;
			if(flag)continue;//每两帧检测一次，增加速度的同时可以避免插帧造成的误差
            //update the background model
       	    if (parser.get<cv::String>("algo") == "MOG2")
                pBackSub->apply(frame, fgMask,parser.get<double>("lr"));
            else
                pBackSub->apply(frame, fgMask);
			

			cv::Mat fgMask3Channels = convertTo3Channels(fgMask);
			if (parser.has("output")){
				videoWriter.write(fgMask3Channels);
            }
			if (parser.has("show")){
				cv::imshow("image",fgMask3Channels);
			}
			//get the input from the keyboard
            int keyboard = cv::waitKey(1);
            if (keyboard == 'q' || keyboard == 27)
                break;
        }
		delete []area;
		if (parser.has("output")){
			videoWriter.release();
		}
	}
        return 0;
}
